%
%~~
%~~  Questões a Serem Respondidas
%~~
%
\chapter{Questionário}
\label{01:chp:questionario}

\section{Questão 1}
\label{01:sec:questao1}

\textbf{Quais são as funções do analisador léxico nos compiladores/interpretadores?}

\textit{\textbf{Resposta}}: O analisador léxico é a interface entre o código-fonte do programa, escrito na linguagem a ser compilada, e as demais partes do compilador. Sua missão lógica é a de fragmentar o código-fonte em componentes básicos, denominados tokens, ou átomos, identificando nesses componentes a identidade lógica dos mesmos na linguagem de programação definida (representação numérica com tamanho fixo), e o valor correspondente associado. A fragmentação do programa em tokens devidamente identificados facilita o processamento da linguagem pelos outros componentes do compilador.
Dentro de sua missão, algumas funções são comuns ao projeto de um analisador léxico, como por exemplo: extração e classificação de tokens, eliminação de delimitadores e comentários, conversão numérica, tratamento de identificadores, identificação de palavras reservadas, recuperação de erros, listagens, geração de tabelas de referências cruzadas, definição e expansão de macros, interação com o sistema de arquivos, compilação condicional e controles de listagens.

\section{Questão 2}
\label{01:sec:questao2}
	\textbf{Quais as vantagens e desvantagens da implementação do analisador léxico como uma fase separada do 
processamento da linguagem de programação em relação à sua implementação como sub-rotina que vai 
extraindo um átomo a cada chamada?}

\textit{\textbf{Resposta}}: Vantagens:  simplicidade na organização modular e sequencial do compilador; extração de informações do código fonte de uma forma padronizada e pré-classificada; facilidade na identificação de erros de nível léxico durante o processo de compilação. Desvantagens: por ser chamado inúmeras vezes durante o processamento de um código  o analisador léxico, da maneira como foi concebido, acaba se tornando um gargalo no processo de compilação, exigindo técnicas para garantir um processamento eficiente; o processamento sequencial gera um grande dependência do análisador sintático em relação ao léxico promovendo um alto acoplamento entre as duas partes e exigindo grande controle de sincronia.

\section{Questão 3}
\label{01:sec:questao3}
\textbf{Defina formalmente, através de expressões regulares sobre o conjunto de caracteres ASCII, a sintaxe de cada 
um dos tipos de átomos a serem extraídos  do texto-fonte pelo analisador léxico, bem como de cada um dos 
espaçadores e comentários.}

\textit{\textbf{Resposta}}: Possíveis classes: identificadores, números, palavras reservadas, caracteres especiais, espaços em branco, comentários, sinais compostos.

\begin{itemize}
\item \textbf{Letra}   $a  |  ...  |  z  |  A  |  ...  |  Z $
\item \textbf{Dígito} $0 | 1 | ... | 9 $
\item \textbf{Identificadores} $letra (letra | digito)* ('\_'  (letra | digito)*)*$
\item \textbf{Números}
\begin{itemize}
\item \textbf{Inteiro} dígito+
\item \textbf{Flutuante} dígito*','dígito+
\end{itemize}
\item \textbf{Palavras Reservadas} $if | else | while | return | void | int | float | char | print | read |  goto$
\item \textbf{Caracteres Especiais} $'.' | ';' | '(' | ')' | '\{' | '\}' | '+' | '-' | '*' | '/' | '\%' | '<' | '>' | '\&' | '|' | '!'$
\item \textbf{Sinais Compostos}	$('>''=') | ('<''=') | ('=''=') | ('\&''\&') | ('|''|') | ('!''=')$
\item \textbf{Espaços em Branco} $(\verb+\+b | \verb+\+r\verb+\+n | \verb+\+n | \verb+\+t)*$
\item \textbf{Comentários} $('//' (qualquer coisa)* ('\verb+\+r\verb+\+n' | \verb+\+n)) | ('/*' (qualquer coisa)* '*/')$
\end{itemize}

\pagebreak 
\section{Questão 4}
\label{01:sec:questao4}
	\textbf{Converta cada uma das expressões regulares, assim obtidas, em autômatos finitos equivalentes que 
reconheçam as correspondentes linguagens por elas definidas.}

\begin{figure}[h!]
	\center
	\includegraphics[scale=0.9]{images/Identificadores.png}
	\label{img:identificadores}
	\caption{Identificadores}
\end{figure}

\begin{figure}[h!]
	\center
	\includegraphics[scale=0.9]{images/Numeros.png}
	\label{img:numeros}
	\caption{Números Inteiros e Ponto Flutuantes}
\end{figure}

\begin{figure}[h!]
	\center
	\includegraphics[scale=0.9]{images/PalavrasReservadas.png}
	\label{img:preservadas}
	\caption{Palavras Reservadas}
\end{figure}

\begin{figure}[h!]
	\center
	\includegraphics[scale=0.9]{images/CaracteresEspeciais.png}
	\label{img:cespeciais}
	\caption{Caracteres Especiais}
\end{figure}

\begin{figure}[h!]
	\center
	\includegraphics[scale=0.9]{images/SinaisCompostos.png}
	\label{img:kohler_facial_expr}
	\caption{Sinais Compostos}
\end{figure}

\begin{figure}[h!]
	\center
	\includegraphics[scale=0.9]{images/EspacosBrancos.png}
	\label{img:comentespacosbranco}
	\caption{Comentários e Espaços em Branco}
\end{figure}

\pagebreak
\section{Questão 5}
\label{01:sec:questao5}
\textbf{	Crie um autômato único que aceite todas essas linguagens a partir de um mesmo estado inicial, mas que 
apresente um estado final diferenciado para cada uma delas.}

\begin{figure}[h!]
	\center
	\includegraphics[scale=0.75]{images/LexicoCompleto.png}
	\label{img:automatocompleto}
	\caption{Autômato Completo}
\end{figure}

\pagebreak
\section{Questão 6}
\label{01:sec:questao6}
	\textbf{Transforme o autômato assim obtido em um transdutor, que emita como saída o átomo encontrado  ao 
abandonar cada um dos estados finais para iniciar o reconhecimento de mais um átomo do texto.}
	
\begin{figure}[h!]
	\center
	\includegraphics[scale=0.75]{images/Transdutor.png}
	\label{img:transdutor}
	\caption{Transdutor}
\end{figure}

\pagebreak
\section{Questão 7}
\label{01:sec:questao7}
\textbf{	Converta o transdutor assim obtido em uma sub-rotina, escrita na linguagem de programação de sua 
preferência. Não se esqueça que o final de cada átomo é determinado ao ser encontrado o primeiro símbolo do 
átomo ou do espaçador seguinte. Esse símbolo não pode ser perdido, devendo-se, portanto, tomar os cuidados de 
programação que forem necessários para reprocessá-los, apesar de já terem sido lidos pelo autômato.}

\textit{\textbf{Resposta}}: Conforme descrito no site da disciplina, na seção de entrega do exercício, ao invés de implementarmos a sub-rotina, criamos uma tabela de estados para representação do transdutor. Essa tabela foi criada em arquivo texto (tabela\_transicao\_estados.txt) cuja a primeira linha indica o número de estados de aceitação, ou seja, os estados a partir dos quais será gerado o token quando uma nova entrada direcionar o fluxo de volta para o estado inicial; a segunda contém o número de todos os estados de aceitação separados por espaço; a partir da terceira linha vem a tabela que está organizada por linhas da seguinte forma: $<nº$ do estado atual$>$ $<$caractere lido$>$ $<nº$ do próximo estado$>$.

\section{Questão 8}
\label{01:sec:questao8}
	\textbf{Crie um programa principal que chame repetidamente a sub-rotina assim construída, e a aplique sobre um 
arquivo do tipo texto contendo o texto-fonte a ser analisado. Após cada chamada, esse programa principal deve 
imprimir as duas componentes do átomo extraído (o tipo e o valor do átomo encontrado). Faça o programa parar 
quando o programa principal receber do analisador léxico um átomo especial indicativo da ausência de novos 
átomos no texto de entrada.}

\textit{\textbf{Resposta}}: O programa feito encontra-se no arquivo main.c.

\section{Questão 9}
\label{01:sec:questao9}
\textbf{Relate detalhadamente o funcionamento do analisador léxico assim construído, incluindo no relatório: 
descrição teórica do programa; descrição da sua estrutura; descrição de seu funcionamento; descrição dos testes 
realizados e das saídas obtidas.}

\subsection{Descrição Teórica}
\label{02:sec:descricaoteorica}
O Analisador Léxico é reponsável por, a partir de um arquivo de entrada, realizar a fragmentação desse arquivo em tokens de elementos da linguagem. O programa funciona lendo caractere por caractere do arquivo de entrada e processando os caracteres de acordo com o estado do transdutor em que se encontra. Quando um novo caractere não previsto é recebido, e o estado do transdutor se encontra num estado final de reconhecimento, então gera-se um novo token, correspondete a cadeia lida anteriormente, e volta-se para o estado inicial para continuar o processamento do arquivo.

\subsection{Estrutura e Funcionamento}
\label{03:sec:estruturaefuncionamento}
O programa foi separado em três arquivos, sendo "lexico.h" um arquivo de cabeçalho correspondente a todas as funcionalidades do analisador léxico, "lexico.c" o arquivo de implementação das funcionalidades e, por fim, "main.c" que corresponde ao programa de teste do analisador léxico. Além destes temos três arquivos adicionais que são "tabela\_transicao\_estados.txt" que é o arquivo contendo a tabela de transição de estados do transdutor, carregada na memória durante a inicialização do léxico, "palavras\_reservadas.txt" que é a tabela de todas as palavras reservadas da linguagem (esta também é carregada na inicialização) e , por último, temos o arquivo "entrada.txt" que é o arquivo de testes.

Ao executar o programa o léxico é inicializado com o arquivo entrada que contém o código de testes. Começa-se então um laço que é responsável por chamar o método getToken do léxico a fim de obter os tokens correspondentes do arquivo de entrada. A cada chamada do getToken o léxico inicia o processamento dos caracteres do arquivo segundo a tabela de transição de estados carregada na memória. O processamento dos caracteres é feito através de um laço de leitura no getToken. As saídas são impressas conforme os tokens encontrados. Quando o programa teste recebe um token com valor nulo encerra-se o laço de testes pois chegou-se ao final do arquivo fonte.

\section{Questão 10}
\label{01:sec:questao10}
	\textbf{Explique como enriquecer esse analisador léxico com um expansor de macros do tipo \#DEFINE, não 
paramétrico nem recursivo, mas que permita a qualquer macro chamar outras macros, de forma não cíclica. (O 
expansor de macros não precisa ser implementado).}

\textit{\textbf{Resposta}}: Para implementar a macro muitos compiladores optam pelo uso de um passo inicial, encarregado de efetuar o pré-processamento do texto original, convertendo-o para uma forma, tratável pelo compilador, que nao apresenta definições nem chamadas de macros. Outros compiladores executam esta operação por meio de rotinas comandadas pelo analisador léxico. Neste caso, entretanto, há em geral uma comunicação entre os analisadores léxico e sintático, no sentido de obter-se, do analisador sintático, dados adicionais sobre a expansão a ser realizada, tais como informações acerca do escopo das macros no texto-fonte.



